/* 发布-订阅模式 */

// 调度中心
class EventBus {
  constructor() {
    // 一堆订阅者
    this.subscribers = {};
  }

  /* 任意订阅者 订阅任意事件 */
  subscribe(event, subscriber) {
    /* 如果事件类型事先类型 事先不存在 */
    if (!this.subscribers[event]) {
      // 就初始化一个空的订阅者列表
      this.subscribers[event] = [];
    }

    // 将当前订阅者加入该事件的观察者列表
    this.subscribers[event].push(subscriber);
  }

  /* 任意订阅者 随时随地取消对任意事件的订阅 */
  unsubscribe(event, subscriber) {
    if (this.subscribers[event]) {
      const index = this.subscribers[event].indexOf(subscriber);
      if (index !== -1) {
        this.subscribers[event].splice(index, 1);
      }
    }
  }

  /* 发布特定事件类型 */
  publish(event, data) {
    // 通知该事件的所有订阅者响应
    if (this.subscribers[event]) {
      this.subscribers[event].forEach((subscriber) => subscriber.onMsg(data));
    }
  }
}

// 订阅者
class Subscriber {
  constructor(name) {
    this.name = name;
  }

  onMsg(data) {
    console.log(`${this.name} 收到通知:`, data);
  }
}

// 示例用法

// 创建一条事件总线
const eventBus = new EventBus();

// 创建2个订阅者
const sub1 = new Subscriber("订阅者 1");
const sub2 = new Subscriber("订阅者 2");

// 特定订阅者 订阅特定事件
eventBus.subscribe("事件1", sub1);
eventBus.subscribe("事件1", sub2);

// 特定订阅者 订阅特定事件
eventBus.subscribe("事件2", sub2);

// 事件发布事件 (事件类型,事件数据)
eventBus.publish("事件1", "Hello, subscribers!");
eventBus.publish("事件2", "Hi there!");

// 取消订阅：技术事件从此没有了康哥的身影
// 康哥从此以后不再关注技术 潜心钻研东方艺术
eventBus.unsubscribe("事件1", sub2);
console.log("=========康哥潜心钻研东方艺术===========");

eventBus.publish("事件1", "Hello again!");
